﻿using ConsoleDemo.InterfaceSegregation;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Reflection;

namespace ConsoleDemo.ReflectionDemo
{
    /// <summary>
    /// 单元测试、依赖注入、泛型编程都是基于反射机制的。
    /// 反射毕竟是动态地去内存中获取对象的描述、对象类型的描述，再用这些描述去创建新的对象，整个过程会影响程序性能，所以不要盲目过多地使用反射
    /// </summary>
    internal class SimpleDemo
    {
        //初探反射
        public static void Call()
        {
            // ITank、HeavyTank 这些都算静态类型
            ITank tank = new HeavyTank();

            Type tankType = tank.GetType();
            object o = Activator.CreateInstance(tankType);
            MethodInfo fireMethod = tankType.GetMethod("Fire");
            MethodInfo RunMethod = tankType.GetMethod("Run");
            fireMethod.Invoke(o, null);
            RunMethod.Invoke(o, null);

            //CreateInstance 创建出来的对象是 object 的，我们并不知道它的静态类型是什么。
        }

        //封装好了的反射最重要的一个功能就是 依赖注入(DI,Dependency Injection)
        //依赖注入框架 Microsoft.Extensions.DependencyInjection
        public static void Call2()
        {
            // ServiceCollection 就是容器
            var sc = new ServiceCollection();
            // 添加 ITank，并设置其对应的实现类是 HeavyTank
            sc.AddScoped(typeof(ITank), typeof(HeavyTank));
            var sp = sc.BuildServiceProvider();
            // ===========分割线===========
            // 分割线上面是整个程序的一次性注册，下面是具体使用
            ITank tank = sp.GetService<ITank>();
            tank.Fire();
        }
    }
}
